// Fill out your copyright notice in the Description page of Project Settings.

#include "CameraManager.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Engine/World.h"
#include "Kismet/GameplayStatics.h"
#include "GameSettingsManager.h"

// 定义默认相机设置
#define DEFAULT_CAMERA_DISTANCE 800.0f
#define DEFAULT_MIN_DISTANCE 200.0f
#define DEFAULT_MAX_DISTANCE 1500.0f
#define DEFAULT_HEIGHT_OFFSET 200.0f
#define DEFAULT_MOVEMENT_SMOOTH_FACTOR 3.0f
#define DEFAULT_ROTATION_SMOOTH_FACTOR 5.0f
#define DEFAULT_COLLISION_RADIUS 25.0f
#define DEFAULT_CAMERA_SENSITIVITY 1.0f

ACameraManager::ACameraManager()
{
    // 使用Winston日志记录相机管理器初始化
    FWinstonLogger::Get().Info(TEXT("CameraManager"), TEXT("Camera manager initializing"));

    // 设置此Actor可在每一帧调用Tick()
    PrimaryActorTick.bCanEverTick = true;

    // 创建弹簧臂组件
    SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
    SpringArm->SetupAttachment(RootComponent);
    SpringArm->bUsePawnControlRotation = false;
    SpringArm->bInheritPitch = true;
    SpringArm->bInheritYaw = false;
    SpringArm->bInheritRoll = false;
    
    // 启用碰撞避免
    SpringArm->bDoCollisionTest = true;
    SpringArm->ProbeChannel = ECC_Camera;
    SpringArm->ProbeSize = DEFAULT_COLLISION_RADIUS;
    SpringArm->bEnableCameraLag = true;
    SpringArm->CameraLagSpeed = DEFAULT_MOVEMENT_SMOOTH_FACTOR;
    SpringArm->bEnableCameraRotationLag = true;
    SpringArm->CameraRotationLagSpeed = DEFAULT_ROTATION_SMOOTH_FACTOR;

    // 创建相机组件
    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);
    Camera->bUsePawnControlRotation = false;

    // 设置根组件
    RootComponent = SpringArm;

    // 初始化相机设置
    TargetDistance = DEFAULT_CAMERA_DISTANCE;
    MinDistance = DEFAULT_MIN_DISTANCE;
    MaxDistance = DEFAULT_MAX_DISTANCE;
    HeightOffset = DEFAULT_HEIGHT_OFFSET;
    TargetRotation = FRotator(45.0f, 0.0f, 0.0f);
    MovementSmoothFactor = DEFAULT_MOVEMENT_SMOOTH_FACTOR;
    RotationSmoothFactor = DEFAULT_ROTATION_SMOOTH_FACTOR;
    bCollisionAvoidanceEnabled = true;
    CollisionRadius = DEFAULT_COLLISION_RADIUS;
    CameraSensitivity = DEFAULT_CAMERA_SENSITIVITY;

    // 初始化观察目标
    ObservedTarget = nullptr;

    // 记录相机管理器初始化完成
    FWinstonLogger::Get().Debug(TEXT("CameraManager"), TEXT("Camera manager initialized"));
}

void ACameraManager::BeginPlay()
{
    Super::BeginPlay();

    // 使用Winston日志记录开始游戏
    FWinstonLogger::Get().Info(TEXT("CameraManager"), TEXT("BeginPlay called"));

    // 获取游戏设置管理器
    GameSettingsManager = UGameSettingsManager::Get(this);
    if (GameSettingsManager)
    {
        // 应用相机设置
        ApplyCameraSettings();
        
        FWinstonLogger::Get().Debug(TEXT("CameraManager"), TEXT("Game settings manager initialized"));
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("CameraManager"), TEXT("Failed to get game settings manager"));
    }

    // 设置初始相机参数
    SpringArm->TargetArmLength = TargetDistance;
    SpringArm->SetRelativeRotation(TargetRotation);

    // 如果没有设置观察目标，尝试找到玩家角色
    if (!ObservedTarget)
    {
        APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
        if (PlayerPawn)
        {
            SetTarget(PlayerPawn);
        }
    }
}

void ACameraManager::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    // 更新相机
    UpdateCamera(DeltaTime);
}

void ACameraManager::SetTarget(AActor* Target)
{
    ObservedTarget = Target;
    
    // 记录观察目标设置
    if (ObservedTarget)
    {
        FWinstonLogger::Get().Debug(TEXT("CameraManager"), 
            TEXT("Observed target set: %s"), 
            *ObservedTarget->GetName());
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("CameraManager"), TEXT("Observed target cleared"));
    }
}

UCameraComponent* ACameraManager::GetCamera() const
{
    return Camera;
}

void ACameraManager::SetCameraDistance(float NewDistance)
{
    // 验证距离值
    TargetDistance = FMath::Clamp(NewDistance, MinDistance, MaxDistance);
    SpringArm->TargetArmLength = TargetDistance;
    
    // 记录相机距离设置
    FWinstonLogger::Get().Debug(TEXT("CameraManager"), TEXT("Camera distance set to: %f"), TargetDistance);
}

void ACameraManager::SetCameraHeightOffset(float NewHeightOffset)
{
    HeightOffset = NewHeightOffset;
    
    // 记录高度偏移设置
    FWinstonLogger::Get().Debug(TEXT("CameraManager"), TEXT("Camera height offset set to: %f"), HeightOffset);
}

void ACameraManager::SetCameraRotation(FRotator NewRotation)
{
    TargetRotation = NewRotation;
    SpringArm->SetRelativeRotation(TargetRotation);
    
    // 记录相机旋转设置
    FWinstonLogger::Get().Debug(TEXT("CameraManager"), 
        TEXT("Camera rotation set to: Pitch=%f, Yaw=%f, Roll=%f"), 
        TargetRotation.Pitch, TargetRotation.Yaw, TargetRotation.Roll);
}

void ACameraManager::SetCollisionAvoidanceEnabled(bool bEnable)
{
    bCollisionAvoidanceEnabled = bEnable;
    SpringArm->bDoCollisionTest = bEnable;
    
    // 记录碰撞避免设置
    FWinstonLogger::Get().Debug(TEXT("CameraManager"), 
        TEXT("Collision avoidance %s"), 
        bEnable ? TEXT("enabled") : TEXT("disabled"));
}

void ACameraManager::SetCameraSensitivity(float NewSensitivity)
{
    // 验证灵敏度值
    CameraSensitivity = FMath::Max(0.1f, NewSensitivity);
    
    // 记录相机灵敏度设置
    FWinstonLogger::Get().Debug(TEXT("CameraManager"), TEXT("Camera sensitivity set to: %f"), CameraSensitivity);
    
    // 如果游戏设置管理器存在，同步设置
    if (GameSettingsManager)
    {
        GameSettingsManager->SetCameraSensitivity(CameraSensitivity);
    }
}

void ACameraManager::UpdateCamera(float DeltaTime)
{
    if (!ObservedTarget)
    {
        return;
    }

    // 计算目标位置
    FVector TargetLocation = ObservedTarget->GetActorLocation();
    TargetLocation.Z += HeightOffset;
    
    // 平滑移动相机
    FVector SmoothedLocation = SmoothCameraMovement(TargetLocation, DeltaTime);
    
    // 设置相机位置
    SetActorLocation(SmoothedLocation);
    
    // 处理碰撞避免
    if (bCollisionAvoidanceEnabled)
    {
        HandleCollisionAvoidance();
    }
}

void ACameraManager::HandleCollisionAvoidance()
{
    // 主要通过SpringArm组件的内置碰撞检测实现
    // 这里可以添加额外的自定义碰撞处理逻辑
    
    // 记录碰撞状态（可选，调试用）
    // if (SpringArm->bIsCameraFixed)
    // {
    //     FWinstonLogger::Get().Debug(TEXT("CameraManager"), TEXT("Camera collision detected"));
    // }
}

FVector ACameraManager::SmoothCameraMovement(const FVector& TargetLocation, float DeltaTime)
{
    // 使用SpringArm的内置滞后系统进行平滑
    // 这里也可以实现自定义的平滑算法
    return FMath::VInterpTo(GetActorLocation(), TargetLocation, DeltaTime, MovementSmoothFactor);
}

FRotator ACameraManager::SmoothCameraRotation(const FRotator& TargetRotation, float DeltaTime)
{
    // 使用SpringArm的内置滞后系统进行平滑
    // 这里也可以实现自定义的平滑算法
    return FMath::RInterpTo(SpringArm->GetRelativeRotation(), TargetRotation, DeltaTime, RotationSmoothFactor);
}

void ACameraManager::ApplyCameraSettings()
{
    if (!GameSettingsManager)
    {
        return;
    }
    
    // 应用相机灵敏度设置
    SetCameraSensitivity(GameSettingsManager->GetCameraSensitivity());
    
    // 记录设置应用
    FWinstonLogger::Get().Debug(TEXT("CameraManager"), TEXT("Camera settings applied"));
}

void ACameraManager::OnSettingsChanged()
{
    // 当设置变更时调用
    ApplyCameraSettings();
}